import struct
from typing import Tuple, Any, Union


class ParseStringRes:
    """字符串解析结果类
    
    与Java版本对应的结果类，存储解析出的字符串和下一个位置
    """
    def __init__(self, str_value: str, next_pos: int):
        self.str = str_value
        self.next = next_pos

class Parser:
    """数据解析工具类"""
    @staticmethod
    def address_to_uid(pageNumber:int,offset_int):
        return pageNumber << 16 | offset_int

    @staticmethod
    def uid_to_address(uid:int):
        # 从UID获取页面ID和偏移量
        page_id = uid >> 16
        offset = uid & 0xFFFF
        return [page_id, offset]
        
    @staticmethod
    def short_to_bytes(value: int) -> bytes:
        """将short值转换为字节数组"""
        return struct.pack('<H', value)
    
    @staticmethod
    def int_to_bytes(value: int) -> bytes:
        """将int值转换为字节数组"""
        return struct.pack('<I', value)
        
    @staticmethod
    def long_to_bytes(value: int) -> bytes:
        """将long值转换为字节数组"""
        return struct.pack('<Q', value)
    
    @staticmethod
    def parse_int(data: bytes) -> int:
        """从字节数组解析int值"""
        if len(data) < 4:
            # 用 '\x00' 填充到 4 字节
            data = data.ljust(4, b'\x00')
        return struct.unpack('<I', data[:4])[0]
    
    @staticmethod
    def parse_long(data: bytes) -> int:
        """从字节数组解析long值"""
        if len(data) < 8:
            # 用 '\x00' 填充到 8 字节
            data = data.ljust(8, b'\x00')  # 使用ljust来填充字节
        return struct.unpack('<Q', data[:8])[0]




    @staticmethod
    def string_to_bytes(s: str) -> bytes:
        """将字符串转换为字节数组（带长度前缀）"""
        s_bytes = s.encode('utf-8')
        length = len(s_bytes).to_bytes(4, 'little')
        return length + s_bytes

    @staticmethod
    def parse_short(data:bytes) -> int:
        # 小字母有符号，大字母无符号
        if len(data) < 2:
            data = data.ljust(2, b'\x00')
        return struct.unpack('<H', data[:2])[0]

    @staticmethod
    def parse_string(data: bytes) :
        """从字节数组解析字符串

        Returns:
            ParseStringRes对象，包含字符串和下一个位置
        """
        if len(data) < 4:
            return "", 0
        # 字段名称都是长度4B+后续的字符串
        length = Parser.parse_int(data[:4])
        # 若数据总长小于则出错
        if len(data) < 4 + length:
            return "", 0
        # 解析字符串
        s = data[4:4 + length].decode('utf-8')
        # 当前字符串和这是下一个的开始位置
        return s, 4 + length
    @staticmethod
    def str_to_uid(key: str) -> int:
        """将字符串转换为UID
        
        使用与Java版本相同的哈希算法
        """
        seed = 13331
        res = 0
        for b in key.encode():
            res = res * seed + b
        return res
        
    @staticmethod
    def float_to_uid(value: float) -> int:
        """将浮点数转换为UID
        
        将浮点数转换为字节表示，然后计算哈希值作为UID
        """
        # 将浮点数转换为字节表示
        float_bytes = struct.pack('<d', value)
        
        # 使用类似str_to_uid的哈希算法
        seed = 13331
        res = 0
        for b in float_bytes:
            res = res * seed + b
        return res